home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 151-175 / scopedisk168 / tinytools / filtex / filtex.asm < prev    next >
Assembly Source File  |  1995-03-19  |  7KB  |  255 lines

  1. ; Filter non-text bytes from pipe stream.
  2.  
  3.        INCLUDE "/include/init.i"
  4.  
  5. ; Local Equs
  6. ; FilTex uses a buffer split into two 1000 byte parts, the first for writing,
  7. ; the last part for reading. Reads/Writes are HalfBufSize bytes large max.
  8.  
  9. DefaultThreshold EQU   4
  10. BufSize                 EQU    2000                    ; Keep this one < 32K
  11. HalfBufSize     EQU    BufSize/2
  12.  
  13. ; Variable storage
  14.  
  15.        STRUCT  ArgArray,(4+1)*4
  16.        LONG    InputHandle
  17.        LONG    StdOutput
  18.        WORD    Threshold
  19.        SIZE
  20.  
  21. ; Regs
  22.  
  23. WriteBufIndex  EQUR    D4
  24. ReadBufIndex   EQUR    D5
  25. ReadBytesLeft  EQUR    D6
  26. LatestByte     EQUR    D7
  27. BufferPtr      EQUR    A2
  28. FilterTablePtr EQUR    A3
  29. ErrorStrPtr    EQUR    A4
  30.  
  31. ; Start
  32.  
  33.        STACK   4000
  34.        INIT
  35.  
  36. ; Let ARP interpret the commandline
  37.  
  38.        MOVE.L  ComLineBase(GP),A0
  39.        MOVE.L  ComLineSize(GP),D0
  40.        LEA     HelpMsg(PC),A1
  41.        LEA     ArgArray(GP),A2
  42.        LEA     Template(PC),A3
  43.        MOVE.L  A1,(A2)
  44.        CALL    GADS
  45.        MOVE.L  (A2),ErrorStrPtr
  46.        TST.L   D0
  47.        BEQ     ErrorExit
  48.        BMI     ErrorExit
  49.  
  50. ; Fetch & check the threshold value.
  51.  
  52.        LEA     BadThreshold(PC),ErrorStrPtr
  53.        MOVE.W  #DefaultThreshold,Threshold(GP)
  54.        MOVE.L  ArgArray+4(GP),A0
  55.        MOVE.L  A0,D0
  56.        BEQ.S   UseDefault
  57.        CALL    Atol
  58.        BEQ     ErrorExit
  59.        CMP.L   #HalfBufSize,D0
  60.        BHI     ErrorExit
  61.        MOVE.W  D0,Threshold(GP)
  62.        BEQ     ErrorExit
  63. UseDefault:
  64.  
  65. ; Check if the source is STDIN, if so open that.
  66.  
  67.        MOVE.L  ArgArray(GP),A0
  68.        LEA     StdinID(PC),A1
  69.        CALL    Strcmp
  70.        BNE.S   NoStdin
  71.        CALL    Input
  72.        MOVE.L  D0,InputHandle(GP)
  73.        BRA.S   InFileOpened
  74. NoStdin:
  75.  
  76. ; Else open a normal source file (Tracked)
  77.  
  78.        LEA     SourceOpenError(PC),ErrorStrPtr
  79.        MOVE.L  ArgArray(GP),D1
  80.        MOVE.L  #MODE_OLDFILE,D2
  81.        CALL    ArpOpen
  82.        MOVE.L  D0,InputHandle(GP)
  83.        BEQ     ErrorExit
  84. InFileOpened:
  85.  
  86. ; Fetch the StdOutput
  87.  
  88.        CALL    Output
  89.        MOVE.L  D0,StdOutput(GP)
  90.  
  91. ; Alloc tracked mem for the read/write buffer.
  92.  
  93.        LEA     OutOfMem(PC),ErrorStrPtr
  94.        MOVE.L  #BufSize+1,D0                   ; add 1 to allow for LF termination
  95.        MOVEQ   #0,D1
  96.        CALL    ArpAllocMem
  97.        TST.L   D0
  98.        BEQ     ErrorExit
  99.        MOVE.L  D0,BufferPtr
  100.  
  101. ; Initialize for the filtered copy loop
  102.  
  103.        LEA     FilterTableBase(PC),FilterTablePtr
  104.        MOVEQ   #0,WriteBufIndex
  105.  
  106. ; Read next chunk of bytes.
  107.  
  108. DoNextRead:
  109.        LEA     ReadError(PC),ErrorStrPtr
  110.        MOVEQ   #0,ReadBufIndex
  111.        MOVE.W  #HalfBufSize,ReadBufIndex
  112.        MOVE.L  InputHandle(GP),D1
  113.        MOVE.L  BufferPtr,D2
  114.        ADD.L   ReadBufIndex,D2
  115.        MOVE.L  ReadBufIndex,D3
  116.        CALL    Read
  117.        MOVE.W  D0,ReadBytesLeft
  118.        BMI     ErrorExit
  119.        BEQ.S   TryToWriteWriteBuffer
  120.  
  121. ; Find text bytes.
  122.  
  123. CheckForTextBytes:
  124.        MOVEQ   #0,LatestByte
  125.        MOVE.B  0(BufferPtr,ReadBufIndex.W),LatestByte
  126.        ADDQ.W  #1,ReadBufIndex
  127.        SUBQ.W  #1,ReadBytesLeft
  128.        TST.B   0(FilterTablePtr,LatestByte.W)
  129.        BEQ.S   TryToWriteWriteBuffer
  130.  
  131. ; Process text bytes
  132.  
  133.        MOVE.B  LatestByte,0(BufferPtr,WriteBufIndex.W)
  134.        ADDQ.W  #1,WriteBufIndex
  135.        CMP.W   #HalfBufSize,WriteBufIndex
  136.        BNE.S   CheckReadBufStatus
  137.  
  138. ; Check if the number of bytes to write equals or exceeds the threshold
  139.  
  140. TryToWriteWriteBuffer:
  141.        CMP.W   Threshold(GP),WriteBufIndex
  142.        BLO.S   NeLeWritezPas
  143.  
  144. ; Check if string is null-terminated (if requested to do so)
  145.  
  146.        TST.L   ArgArray+12(GP)                 ; Check NULT switch
  147.        BEQ.S   NoNullCheck
  148.        TST.B   LatestByte
  149.        BNE.S   NeLeWritezPas
  150. NoNullCheck:
  151.  
  152. ; Terminate write with a linefeed if needed & not prohibited
  153.  
  154.        CMP.B   #10,-1(BufferPtr,WriteBufIndex.W)
  155.        BEQ.S   DoTheWrite
  156.        TST.L   ArgArray+8(GP)                  ; Check NOLF switch
  157.        BNE.S   DoTheWrite
  158.        MOVE.B  #10,0(BufferPtr,WriteBufIndex.W)
  159.        ADDQ.W  #1,WriteBufIndex
  160.  
  161. ; The actual write to the StdOutput
  162.  
  163. DoTheWrite:
  164.        LEA     WriteError(PC),ErrorStrPtr
  165.        MOVE.L  StdOutput(GP),D1
  166.        MOVE.L  BufferPtr,D2
  167.        MOVE.W  WriteBufIndex,D3
  168.        EXT.L   D3
  169.        CALL    Write
  170.        CMP.L   D0,D3
  171.        BNE.S   ErrorExit
  172.  
  173. ; Check if user hit ^C 
  174.  
  175.        SUB.L   A1,A1
  176.        CALL    CheckAbort
  177.        MOVE.L  A1,ErrorStrPtr
  178.        TST.L   D0
  179.        BNE.S   ErrorExit
  180. NeLeWritezPas:
  181.  
  182. ; Reset the write buffer index.
  183.  
  184.        MOVEQ   #0,WriteBufIndex
  185.  
  186. ; Check if no more read bytes left, if so read, exit if last read had zero length
  187. ; (An adjective, verb and a noun. YOU try 'n make a natural language interpreter!)
  188.  
  189. CheckReadBufStatus:
  190.        TST.W   ReadBytesLeft
  191.        BNE     CheckForTextBytes
  192.        CMP.W   #HalfBufSize,ReadBufIndex
  193.        BNE     DoNextRead
  194.  
  195. ; Done, cleanup
  196.  
  197. Exit:
  198.        CLR.W   ReturnCode(GP)
  199.        SUB.L   ErrorStrPtr,ErrorStrPtr
  200. ErrorExit:
  201.  
  202. ; Display error string, if any, and exit
  203.  
  204.        MOVE.L  ErrorStrPtr,D0
  205.        BEQ.S   NoErrorMsg
  206.        MOVE.L  D0,A1
  207.        CALL    Puts
  208. NoErrorMsg:
  209.        RTS
  210.  
  211. ; The string section
  212.  
  213. Template:
  214.        DC.B    'File/a,THRESH/k,NOLF/s,NULT/s',0
  215. HelpMsg:
  216.        DC.B    'FilTex - filter out non-text.',10
  217.        DC.B    'Usage: FilTex <File | STDIN> [THRESH #] [NOLF] [NULT]',0
  218. StdinID:
  219.        DC.B    'STDIN',0
  220. BadThreshold:
  221.        DC.B    'Illegal threshold value',0
  222. SourceOpenError:
  223.        DC.B    'Could not open source file',0
  224. OutOfMem:
  225.        DC.B    'Out of memory!',0
  226. ReadError:
  227.        DC.B    'Error while reading',0
  228. WriteError:
  229.        DC.B    'Error while writing',0
  230.        CNOP    0,4
  231.  
  232. ; This is the filtering array
  233.  
  234.        DC.B    'TextTab:'
  235. FilterTableBase:
  236. ;               0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  237.        DC.B    000,000,000,000,000,000,000,000,000,$09,$0A,000,000,000,000,000 ;0
  238.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;1
  239.        DC.B    ' ','!','"','#','$','%','&',$27,'(',')','*','+',',','-','.','/' ;2
  240.        DC.B    '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?' ;3
  241.        DC.B    000,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O' ;4
  242.        DC.B    'P','Q','R','S','T','U','V','W','X','Y','Z','[','\',']','^','_' ;5
  243.        DC.B    000,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o' ;6
  244.        DC.B    'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',000 ;7
  245.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;8
  246.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;9
  247.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;A
  248.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;B
  249.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;C
  250.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;D
  251.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;E
  252.        DC.B    000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;F
  253. ;               0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  254.        END
  255.